using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace Tino.Controls
{
    public partial class EntriesListBox : UserControl
    {
        #region Nested Classes

        protected class EntriesListBoxItem
        {
            string title;
            int id;
            int imageIndex;

            public int ID { get { return id; } }
            
            public string Title
            { 
                get { return title; }
                set { title = value; }
            }

            public int ImageIndex
            { 
                get { return imageIndex; }
                set { imageIndex = value; }
            }

            public EntriesListBoxItem(string Title, int ID, int ImageIndex)
            {
                title = Title;
                id = ID;
                imageIndex = ImageIndex;
            }
        }

        #endregion

        Color alternateColor = Color.WhiteSmoke;
        Color selectedItemColor = Color.PeachPuff;
        ImageList images;

        public event SelectedEntryChangedEventHandler SelectedEntryChanged;

        public EntriesListBox()
        {
            InitializeComponent();
            list.Font = this.Font;
        }

        #region Public Members

        public virtual void OnSelectedEntryChanged(SelectedEntryChangedEventArgs e)
        {
            if (SelectedEntryChanged != null)
                SelectedEntryChanged(this, e);
        }

        public ImageList ImageList
        {
            get { return images; }
            set { images = value; }
        }

        public int SelectedEntryID
        {
            get
            {
                if (list.SelectedIndex == -1) return -1;
                return ((EntriesListBoxItem)list.Items[list.SelectedIndex]).ID;
            }
        }

        public int Count
        {
            get { return list.Items.Count; }
        }

        public int SelectedIndex
        {
            get { return list.SelectedIndex; }
            set { list.SelectedIndex = value; }
        }

        public int IndexAt(Point p)
        {
            return list.IndexFromPoint(p);
        }

        /// <summary>
        /// Redraw the list item at given index with the new icon index
        /// </summary>
        /// <param name="index"></param>
        public void Redraw(int index, int newImageIndex)
        {
            ((EntriesListBoxItem)list.Items[index]).ImageIndex = newImageIndex;
            list.Invalidate(list.GetItemRectangle(index));
        }

        public void Redraw(int index, int newImageIndex, string title)
        {
            ((EntriesListBoxItem)list.Items[index]).ImageIndex = newImageIndex;
            ((EntriesListBoxItem)list.Items[index]).Title = title;
            list.Invalidate(list.GetItemRectangle(index));
        }

        public void BeginUpdate()
        {
            list.BeginUpdate();
        }

        public void EndUpdate()
        {
            list.EndUpdate();
        }

        public void Clear()
        {
            list.Items.Clear();
        }

        public void Add(string EntryTitle, int EntryID, int ImageIndex)
        {
            EntriesListBoxItem item = new EntriesListBoxItem(EntryTitle, EntryID, ImageIndex);
            list.Items.Add(item);
        }

        public void Remove(int index)
        {
            list.Items.RemoveAt(index);
        }

        #endregion

        #region Control event handlers

        void list_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (list.Items.Count > 0 && e.Index > -1)
            {
                EntriesListBoxItem item = (EntriesListBoxItem)list.Items[e.Index];

                Color backColor = (e.Index % 2 == 0 ? Color.White : alternateColor);
                if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
                    backColor = selectedItemColor;

                // Draw background
                using (SolidBrush back = new SolidBrush(backColor))
                {
                    e.Graphics.FillRectangle(back, e.Bounds);
                }

                // Draw icon
                if (item.ImageIndex > -1)
                {
                    if (images != null)
                    {
                        Image img = images.Images[item.ImageIndex];
                        Rectangle imgBox = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, 32, 32);
                        e.Graphics.DrawImage(img, imgBox);
                    }
                }

                // Draw string label
                using (SolidBrush fore = new SolidBrush(Color.Black))
                {
                    e.Graphics.DrawString(item.Title, Font, fore, new Point(e.Bounds.X + 40, e.Bounds.Y + 10));
                }
            }
        }

        void list_MouseDown(object sender, MouseEventArgs e)
        {
            this.OnMouseDown(e);
        }

        void list_SelectedIndexChanged(object sender, EventArgs e)
        {
            int idx = list.SelectedIndex;
            int id = SelectedEntryID;
            OnSelectedEntryChanged(new SelectedEntryChangedEventArgs(idx, id));
        }

        void list_DoubleClick(object sender, EventArgs e)
        {
            this.OnDoubleClick(e);
        }

        #endregion 
    }

    #region Control events

    public delegate void SelectedEntryChangedEventHandler(object sender, SelectedEntryChangedEventArgs e);

    public class SelectedEntryChangedEventArgs : EventArgs
    {
        int selectedEntryIndex;
        int selectedEntryID;

        public int SelectedEntryIndex { get { return selectedEntryIndex; } }
        public int SelectedEntryID { get { return selectedEntryID; } }

        public SelectedEntryChangedEventArgs(int SelectedEntryIndex, int SelectedEntryID)
        {
            selectedEntryIndex = SelectedEntryIndex;
            selectedEntryID = SelectedEntryID;
        }
    }

    #endregion
}
